API Design Pattern of the Week 17: Version Identifier

A pattern from the book “Patterns of API Design: Simplifying Integration with Loosely Coupled Message Exchanges”

Doc SoC (aka ZIO)
ZIO’s Blog
4 min readNov 9, 2023

--

The first 14 patterns in this “API Design Pattern of the Week” series came as LinkedIn articles; Pattern 15 was Rate Limit, Pattern 16 was Context Representation; Pattern 18 is Two in Production. All series members are listed here.

Note: This online excerpt of the pattern predates its final version in the book.

Context

An API that runs in production evolves. New versions with improved functionality are offered over time. At some point in time, the changes of a new version are no longer backwards compatible; this caused existing clients to break.

Problem

How can an API provider indicate its current capabilities as well as the existence of possibly incompatible changes in order to prevent malfunctioning of API clients due to undiscovered interpretation errors?

Forces

  • Accuracy and exact identification of API version
  • Guaranteeing that API changes do not lead to accidentally breaking compability between client and provider on the semantic level
  • Minimizing impact on the client side caused by API changes
  • Traceability of API versions in use for governance

Solution Sketch

Introduce an explicit version indicator. Include this Version Identifier in the API Description and in the exchanged messages. To do the latter, add a Metadata Element to the endpoint address, the protocol header, or the message payload.

Example

In REST APIs the version of different features can be indicated as follows. The version of specific representation formats supported by the client in the content type negotiation headers of HTTP:

GET /customers/1234 Accept: text/json+customer; version=1.0 ...

The version of specific operations is found as part of the resource identifiers:

GET v2/customers/1234 ...

The version of the whole API can also be specified in the host domain name:

GET /customers/1234 Host: v2.api.service.com ...

Another possibility is to specify the version in the payload as in the following JSON example. In the initial version 1.0 of the billing API, the prices were defined in Euro:

{ "version": "1.0", 
"products": [
{ "productId": "ABC123", "quantity": 5; "price": 5.00;
}
]
}

With a new version the requirement of multi-currency was realized. This leads to the new data structure and the new contents of the version element:

{
"version": "2.0",
"products": [
{
"productId": "ABC123",
"quantity": 5;
"price": 5.00;
"currency": "USD"
}
]
}

If no Version Identifier or any other mechanism to indicate a breaking change had been used, old software interpreting the version 2.0 of the message would assume that the product costs 5 EUR although it costs 5 USD. This is because a new attribute has changed the semantics of an existing one. Passing the version in the content type as shown above can eliminate this problem. While it would be possible to introduce a new field priceWithCurrency to avoid this problem, such changes lead to technical debt by aggregating over time, especially in less trivial examples.

Consequences

Forces resolution and other consequences are discussed in our book.

Known Uses

See pattern coverage on our website.

Related Patterns

The visibility and role of an API drive related design decisions. For instance, the different life cycles, deployment frequencies, and release dates of provider(s) and client(s) in a Public API scenario for Frontend Integration make it necessary to plan service evolution beforehand and usually do not allow providers to make arbitrary ad hoc changes to already published APIs due to the impact of such changes on clients (e.g., downtimes, test and migration effort caused). Some or all of these clients might not even be known. A Community API providing Backend Integration capabilities between a few stable communication parties that are maintained on the same release cycle (and share a common roadmap) might be able to employ more relaxed versioning tactics. Finally, a Solution-Internal API connecting a mobile app frontend with a single backend (Frontend Integration) owned, developed, and operated by the same agile team might fall back to an ad hoc, opportunistic approach that relies on frequent, automated unit/integration tests within a continuous integration and delivery practice.

Other Sources

Because versioning is an important aspect of API and service design, there is much discussion about it in different development communities. The strategies differ widely, and versioning strategies are passionately debated. Opinions reach from:

to:

James Higginbotham describes the available options here.

Chapter 11 of “SOA in Practice” (Josuttis 2007) introduces a service life cycle in the context of Service-Oriented Architecture (SOA) design; Chapter 12 discusses versioning. Chapter 13 of “Build APIs you won’t hate” (Sturgeon 2026) discusses seven options for versioning (with the Version Identifier in URLs being one of these options) and their advantages and disadvantages. It also gives implementation hints. Chapter 15 of “SOA with REST” (Erl et al. 2013) deals with Service Versioning for REST.

Schema versioning is introduced in a blog post from Snowplow “Introducing SchemaVer for semantic versioning of schemas”.

References

Erl, Thomas, Benjamin Carlyle, Cesare Pautasso, and Raj Balasubramanian. 2013. SOA with REST — Principles, Patterns and Constraints for Building Enterprise Solutions with REST. Prentice Hall.

Hohpe, Gregor, and Bobby Woolf. 2003. Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions. Addison-Wesley.

Josuttis, Nicolai. 2007. SOA in Practice: The Art of Distributed System Design. O’Reilly.

Sturgeon, Phil. 2016. Build APIs You Won’t Hate. LeanPub. https://leanpub.com/build-apis-you-wont-hate.

Zimmermann, Olaf and Stocker, Mirko and Lübke, Daniel and Zdun, Uwe and Pautasso, Cesare. 2022. Patterns for API Design: Simplifying Integration with Loosely Coupled Message Exchanges, Vaughn Vernon Signature Series, Addison-Wesley Professional.

This book features 44 patterns plus API domain model, decision models, pattern adoption stories, …

This pattern originally appeared on our website https://api-patterns.org.

We follow the standard format for patterns, from context to forces, problem, solution, consequences and known uses. Find out why.

Copyright © 2019–2023 by the authors. All rights reserved.
See
terms and conditions of use.

--

--

Doc SoC (aka ZIO)
ZIO’s Blog

Architectural Decision Maker, Domain-Driven Designer, Serviceorienteer. Co-author of "Patterns for API Design", "Design Practice Reference", Y-Statements, MADR